using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JoyfulHomeJourney.BackEnd.Infrastructure.Atrributes;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Requests.Objects;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Responses;
using JoyfulHomeJourney.BackEnd.Infrastructure.Dtos.Responses.Objects;
using JoyfulHomeJourney.BackEnd.Infrastructure.EFCore;
using JoyfulHomeJourney.BackEnd.Server.EFCore;
using JoyfulHomeJourney.BackEnd.Server.Instances.Extends.Requests;
using JoyfulHomeJourney.BackEnd.Server.Instances.Extends.Responses;
using JoyfulHomeJourney.BackEnd.Server.Interfaces;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace JoyfulHomeJourney.BackEnd.Server.Instances
{
    /// <summary>
    /// 一个类包含了服务类所需的所有仓库表的实例，仅提供给该服务类使用，请将所有服务类所需的仓库表的实例都放在该类中。
    /// 仓库表的实例指提供了操作数据库指定表的所有方法的对象
    /// </summary>
    internal class SysVipPackagesEF
    {
        public SysVipPackagesEF(DbContext dbContext)
        {
            sysVipPackagesServerEF = new SysVipPackagesServerEF(dbContext);
            sysProductsServerEF = new SysProductsServerEF(dbContext);
            vipsServerEF = new VipsServerEF(dbContext);
        }
        public SysVipPackagesServerEF sysVipPackagesServerEF { get; set; }
        public SysProductsServerEF sysProductsServerEF { get; set; }
        public VipsServerEF vipsServerEF { get; set; }
    }
    [InjectClass]
    public class SysVipPackagesServer : ISysVipPackagesServer
    {
        private readonly SysVipPackagesEF _sysVipPackagesEF;//包含所有所需仓库表实现的对象
                                                            // 请不要修改该构造方法,也无需添加属性，而应该在上面的EF类中添加属性和构造函数赋值语句
        public SysVipPackagesServer(DbContext dbContext)
        {
            _sysVipPackagesEF = new SysVipPackagesEF(dbContext);
        }
        public async Task<ResponseApiDto> AddAsync(RequestSysVipPackagesDto dto)
        {
            int affectedRows = 0;
            await _sysVipPackagesEF.sysVipPackagesServerEF.ExecuteInTransactionAsync(async () =>
            {
                // 添加产品 
                var product = dto.ToSysProductsCreateEntity();
                product.PCategory = "sys_vip_packages";
                affectedRows += await _sysVipPackagesEF.sysProductsServerEF.AddAsync(product);
                // 添加会员套餐
                var vipPackage = dto.ToCreateEntity();
                vipPackage.VpProductId = product.PId;
                affectedRows += await _sysVipPackagesEF.sysVipPackagesServerEF.AddAsync(vipPackage);
            });
            return ResponseApiDto.Create(affectedRows);
        }
        private async Task<bool> Exist(string id)
        {
            return await _sysVipPackagesEF.sysVipPackagesServerEF.Query(d => d.VpId == id).AnyAsync();
        }
        public async Task<ResponseApiDto> DeleteAsync(RequestSysVipPackagesDto dto)
        {
            if (!await Exist(dto.id))
            {
                return ResponseApiDto.Fail("该会员套餐不存在");
            }
            int affectedRows = 0;
            await _sysVipPackagesEF.sysVipPackagesServerEF.ExecuteInTransactionAsync(async () =>
            {
                // 删除会员套餐
                var vipPackage = new SysVipPackages { VpId = dto.id };
                var productId = await _sysVipPackagesEF.sysVipPackagesServerEF.Query(d => d.VpId == dto.id).Select(d => d.VpProductId).SingleAsync();
                affectedRows += await _sysVipPackagesEF.sysVipPackagesServerEF.DeleteAsync(vipPackage);
                // 删除产品
                var product = new SysProducts { PId = productId };
                affectedRows += await _sysVipPackagesEF.sysProductsServerEF.DeleteAsync(product);
            });
            return ResponseApiDto.Create(affectedRows);
        }
        public async Task<ResponseApiDto> UpdateAsync(RequestSysVipPackagesDto dto)
        {
            if (!await Exist(dto.id))
            {
                return ResponseApiDto.Fail("该会员套餐不存在");
            }
            int affectedRows = 0;
            await _sysVipPackagesEF.sysVipPackagesServerEF.ExecuteInTransactionAsync(async () =>
            {
                // 更新产品表
                var productId = await _sysVipPackagesEF.sysVipPackagesServerEF.Query(d => d.VpId == dto.id).Select(d => d.VpProductId).SingleAsync();
                var product = dto.ToSysProductsCreateEntity();
                product.PId = productId;
                affectedRows += await _sysVipPackagesEF.sysProductsServerEF.UpdateAllProperNotNullAsync(product);
                // 更新会员套餐表
                var vipPackage = dto.ToCreateEntity();
                affectedRows += await _sysVipPackagesEF.sysVipPackagesServerEF.UpdateAllProperNotNullAsync(vipPackage);
            });
            return ResponseApiDto.Create(affectedRows);
        }
        public async Task<ResponseApiDto> PaginationAsync(int page, int limit, string key,string shopId, string field, bool? order)
        {
            int total = 0;
            List<ResponseSysVipPackagesDto> data = new List<ResponseSysVipPackagesDto>();
            var iq = orderByField(_sysVipPackagesEF.sysVipPackagesServerEF.Query(d =>d.VpProduct.PCsId==shopId&&(key == null || d.VpProduct.PName.Contains(key) || d.VpVip.VName.Contains(key))), field, order ?? true);
            total = await iq.CountAsync();
            List<SysVipPackages> sysVipPackagess = await iq.Skip((page - 1) * limit).Take(limit).ToListAsync();
            foreach (var sysVipPackages in sysVipPackagess)
            {
                var product = await _sysVipPackagesEF.sysProductsServerEF.Query(d => d.PId == sysVipPackages.VpProductId).SingleOrDefaultAsync();
                var responseDto = sysVipPackages.ToResponseDto(product);
                responseDto.VIPName = await _sysVipPackagesEF.vipsServerEF.Query(d => d.VId == responseDto.VIPId).Select(d => d.VName).SingleOrDefaultAsync();
                data.Add(responseDto);
            }
            return ResponseApiDto.Success("数据已获取", new ResponsePaginationDto { total = total, data = data });
        }

        public async Task<ResponseApiDto> GetVipPackages()
        {
            List<ResponseSysVipPackagesDto> data = new List<ResponseSysVipPackagesDto>();
            List<SysVipPackages> sysVipPackagess = await _sysVipPackagesEF.sysVipPackagesServerEF.Query().ToListAsync();
            foreach (var sysVipPackages in sysVipPackagess)
            {
                data.Add(new ResponseSysVipPackagesDto
                {
                    id= sysVipPackages.VpId,
                    name= await _sysVipPackagesEF.sysProductsServerEF.Query(d => d.PId == sysVipPackages.VpProductId).Select(d => d.PName).SingleOrDefaultAsync(),
                });
            }
            return ResponseApiDto.Success("数据已获取", new ResponsePaginationDto { data = data });
        }
        private IQueryable<SysVipPackages> orderByField(IQueryable<SysVipPackages> iq, string field, bool isAsc)
        {
            switch (field)
            {
                case "name":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PName);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PName);
                    }
                    break;
                case "VIPName":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpVipId);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpVipId);
                    }
                    break;
                case "year":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpYear);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpYear);
                    }
                    break;
                case "month":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpMonth);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpMonth);
                    }
                    break;
                case "price":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PPrice);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PPrice);
                    }
                    break;
                case "discount":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PDiscount);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PDiscount);
                    }
                    break;
                case "deduction":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PDeduction);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PDeduction);
                    }
                    break;
                case "saleCount":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PSaleCount);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PSaleCount);
                    }
                    break;
                case "saleSum":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PSaleSum);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PSaleSum);
                    }
                    break;
                case "rating":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PRating);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PRating);
                    }
                    break;
                case "updateAtStr":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PUpdateAt);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PUpdateAt);
                    }
                    break;
                case "createAtStr":
                    if (isAsc)
                    {
                        iq = iq.OrderBy(d => d.VpProduct.PCreateAt);
                    }
                    else
                    {
                        iq = iq.OrderByDescending(d => d.VpProduct.PCreateAt);
                    }
                    break;
                default:
                    iq = iq.OrderByDescending(d => d.VpProduct.PCreateAt);
                    break;
            }
            return iq;
        }
    }
}
